﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Extensil.Common;
using Vibz.TeamAssignment.Common.Entity;

namespace Vibz.TeamAssignment
{
    public partial class TaskSettings : BaseSetting
    {
        AssignmentClient _aClient;
        BackgroundWorker bwConfigure;
        List<TaskGroupOwner> tgOwnersList;
        TeamMember[] teamMemberArray;
        BaseCategory _cat;
        bool _autoLoadOn = false;
        string siteUrl;
        public TaskSettings()
        {
            InitializeComponent();
        }
        internal TaskSettings(BaseCategory category, AssignmentClient client)
            : this()
        {
            txtAssManager.Text = System.Configuration.ConfigurationManager.AppSettings["AssignmentManager"];
            siteUrl = System.Configuration.ConfigurationManager.AppSettings["SPSite"];
            _aClient = client;
            _cat = category;
            Form uForm = client.GetSettingsForm(category);
            uForm.TopLevel = false;
            uForm.Dock = DockStyle.Fill;
            uForm.FormBorderStyle = FormBorderStyle.None;
            uForm.Show();
            tpConnection.Controls.Clear();
            tpConnection.Controls.Add(uForm);
        }
        protected override void OnLoad(EventArgs e)
        {
            int interval = 60;
            int.TryParse(System.Configuration.ConfigurationManager.AppSettings["UpdateInterval"], out interval);
            updateInterval.Value = interval;
            LoadAdminControls();
        }
        void LoadAdminControls()
        {
            tabControl1.TabPages.Remove(tpMasterData);
            tabControl1.TabPages.Remove(tpTaskGroup);
            tabControl1.TabPages.Remove(tpTeamMember);

            if(!_aClient.IsConnected)
            {
                tabControl1.TabPages.Remove(tpTaskView);
                return;
            }
            
            AuthorizeUser();
        }
        private void AuthorizeUser()
        {
            bwConfigure = new BackgroundWorker();
            bwConfigure.WorkerReportsProgress = true;
            bwConfigure.WorkerSupportsCancellation = true;
            bwConfigure.DoWork += new DoWorkEventHandler(bwConfigure_Authorize);
            bwConfigure.ProgressChanged += new ProgressChangedEventHandler(bwConfigure_ProgressChanged);
            bwConfigure.RunWorkerAsync();
        }

        void bwConfigure_Authorize(object sender, DoWorkEventArgs e)
        {
            bwConfigure.ReportProgress(100,
                    new KeyValuePair<string, object>("Authorization",
                        _aClient.IsUserAdmin()));
        }
        void ReloadControl(KeyValuePair<string, object> op)
        {
            switch(op.Key)
            {
                case "ViewColumns":
                    if(op.Value != null)
                    {
                        string[] colNames = (string[])op.Value;
                        lstVisibleColumn.DataSource = colNames;
                    }
                    break;
                case "ColumnSequence":
                    if(op.Value != null)
                    {
                        string[] colNames = (string[])op.Value;
                        for(int i = 0; i < lstVisibleColumn.Items.Count; i++)
                            lstVisibleColumn.SetItemCheckState(i,
                                (colNames.Contains(lstVisibleColumn.Items[i].ToString()) 
                                ? CheckState.Checked 
                                : CheckState.Unchecked));
                    }
                    break;
                case "Authorization":
                    if(op.Value != null && (bool)op.Value)
                    {
                        tabControl1.TabPages.Add(tpTaskGroup);
                        tabControl1.TabPages.Add(tpTeamMember);
                        tabControl1.TabPages.Add(tpMasterData);

                        LoadAdminData();
                    }
                    break;
                case "TeamMember":
                    if(op.Value != null)
                    {
                        List<TeamMember> tMember = (List<TeamMember>)op.Value;
                        teamMemberArray = new TeamMember[tMember.Count];
                        tMember.CopyTo(teamMemberArray);

                        cbOwner.ValueMember = "MemberID";
                        cbOwner.DisplayMember = "MemberID";
                        TeamMember[] ownerList = new TeamMember[tMember.Count];
                        tMember.CopyTo(ownerList);
                        cbOwner.DataSource = ownerList.ToList();

                        cbManager.ValueMember = "MemberID";
                        cbManager.DisplayMember = "MemberID";
                        TeamMember[] managerList = new TeamMember[tMember.Count];
                        tMember.CopyTo(managerList);
                        cbManager.DataSource = managerList.ToList();

                        lstOwners.ValueMember = "MemberID";
                        lstOwners.DisplayMember = "MemberID";
                        TeamMember[] ownerList2 = new TeamMember[tMember.Count];
                        tMember.CopyTo(ownerList2);
                        lstOwners.DataSource = ownerList2.Select(owner => owner.MemberID).ToList();
                        //lstOwners.ItemCheck += new ItemCheckEventHandler(lstOwners_ItemCheck);

                        lstManager.ValueMember = "MemberID";
                        lstManager.DisplayMember = "MemberID";
                        TeamMember[] managerList2 = new TeamMember[tMember.Count];
                        tMember.CopyTo(managerList2);
                        lstManager.DataSource = managerList2.ToList();

                        lstUsers.ValueMember = "ManagerID";
                        lstUsers.DisplayMember = "MemberID";
                        TeamMember[] userList = new TeamMember[tMember.Count];
                        tMember.CopyTo(userList);
                        lstUsers.DataSource = userList.ToList();
                        if(userList.Count() > 0)
                        {
                            lstUsers.SelectedIndex = 0;
                            SetManager();
                        }

                    }
                    break;
                case "TaskGroup":
                    if(op.Value != null)
                    {
                        List<TaskGroup> tGroupList = (List<TaskGroup>)op.Value;

                        foreach(TaskGroup tGroup in tGroupList)
                        {
                            tGroup.GroupOwners = string.Join(",", tgOwnersList
                                .Where(group => group.GroupId == tGroup.ID)
                                .Select(owner => owner.OwnerId)
                                .ToArray());
                        }
                        lstGroups.DataSource = null;
                        lstGroups.DataSource = tGroupList;
                        lstGroups.ValueMember = "GroupOwners";
                        lstGroups.DisplayMember = "Title";
                        
                        if(tGroupList.Count() > 0)
                        {
                            // lstGroups.SelectedIndex = 0; // Bug in this line
                            SetOwnersList();
                        }

                    }
                    break;
                case "TaskGroupOwner":
                    if(op.Value != null)
                    {
                        tgOwnersList = (List<TaskGroupOwner>)op.Value;
                    }
                    break;
                case "BindEvent":
                    lstUsers.SelectedIndexChanged += new EventHandler(lstUsers_SelectedIndexChanged);
                    lstGroups.SelectedIndexChanged += new EventHandler(lstGroups_SelectedIndexChanged);
                    break;
                case "TaskMaster":
                    if(op.Value != null)
                    {
                        List<TaskMasterEntry> tMaster = (List<TaskMasterEntry>)op.Value;
                        dgvMasterData.DataSource = tMaster;
                    }
                    break;
            }
        }
        void bwConfigure_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if(e.UserState.GetType() == typeof(KeyValuePair<string, object>))
            {
                ReloadControl((KeyValuePair<string, object>)e.UserState);
                return;
            }
        }
        void lstManager_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(_autoLoadOn || lstManager.SelectedItems.Count == 0)
                return;
            if(AlertBox.ShowDialog("Are you sure you want to change the Manager for selected user?",
                "Confirm Action", AlertBoxButtons.YesNo) == AlertResult.Yes)
            {
                _aClient.AddTeamMember(((TeamMember)lstUsers.SelectedItem).MemberID,
                    ((TeamMember)lstManager.SelectedItem).MemberID);

                teamMemberArray
                    .Where(mList => mList.MemberID == ((TeamMember)lstUsers.SelectedItem).MemberID)
                    .First()
                    .ManagerID = ((TeamMember)lstManager.SelectedItem).MemberID;
            }
        }

        void lstOwners_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if(_autoLoadOn || lstOwners.SelectedItems.Count == 0)
                return;

            if(AlertBox.ShowDialog("Are you sure you want to add/remove selected user from Task group owners list?",
                "Confirm Action", AlertBoxButtons.YesNo) == AlertResult.Yes)
            {
                string owners = "";
                foreach(object own in lstOwners.CheckedItems)
                {
                    owners += own.ToString() + ",";
                }
                switch(e.NewValue)
                {
                    case CheckState.Checked:
                        _aClient.AddTaskGroupOwner(((TaskGroup)lstGroups.SelectedItem).ID, 
                            lstOwners.Items[lstOwners.SelectedIndex].ToString());

                        owners += lstOwners.Items[lstOwners.SelectedIndex].ToString();
                        break;
                    case CheckState.Unchecked:
                        _aClient.DeleteTaskGroupOwner(((TaskGroup)lstGroups.SelectedItem).ID,
                            lstOwners.Items[lstOwners.SelectedIndex].ToString());
                        owners = owners.Replace(lstOwners.Items[lstOwners.SelectedIndex].ToString(), "");
                        break;
                }

                ((List<TaskGroup>)lstGroups.DataSource)
                    .Where(gList => gList.Title == ((TaskGroup)lstGroups.SelectedItem).Title)
                    .First()
                    .GroupOwners = owners;
            }
        }

        void lstGroups_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(_autoLoadOn || lstGroups.SelectedItems.Count == 0)
                return;
            SetOwnersList();
        }
        void SetOwnersList()
        {
            lstOwners.ItemCheck -= lstOwners_ItemCheck;

            if(lstGroups.SelectedItem == null)
                return;
            string owners = ((TaskGroup)lstGroups.SelectedItem).GroupOwners;
            if(!string.IsNullOrEmpty(owners))
            {
                string[] ownersList = owners.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                for(int i = 0; i < lstOwners.Items.Count; i++)
                    lstOwners.SetItemCheckState(i,
                        (ownersList.Contains(lstOwners.Items[i].ToString()) ? CheckState.Checked : CheckState.Unchecked));
            }
            lstOwners.ItemCheck += lstOwners_ItemCheck;
        }

        void lstUsers_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(_autoLoadOn || lstUsers.SelectedItems.Count == 0)
                return;
            SetManager();
        }

        void SetManager()
        {
            lstManager.SelectedIndexChanged -= lstManager_SelectedIndexChanged;
            _autoLoadOn = true;
            TeamMember[] tManagerList = new TeamMember[teamMemberArray.Count()];
            teamMemberArray.CopyTo(tManagerList, 0);
            lstManager.DataSource = tManagerList
                .Where(mList => mList.MemberID != ((TeamMember)lstUsers.SelectedItem).MemberID).ToArray();

            string manager = ((TeamMember)lstUsers.SelectedItem).ManagerID;
            if(!string.IsNullOrEmpty(manager))
                lstManager.SelectedIndex = lstManager.FindStringExact(manager);
            _autoLoadOn = false;
            lstManager.SelectedIndexChanged += lstManager_SelectedIndexChanged;
        }
        void LoadAdminData()
        {
            bwConfigure = new BackgroundWorker();
            bwConfigure.WorkerReportsProgress = true;
            bwConfigure.WorkerSupportsCancellation = true;
            bwConfigure.DoWork += new DoWorkEventHandler(bwConfigure_LoadData);
            bwConfigure.ProgressChanged += new ProgressChangedEventHandler(bwConfigure_ProgressChanged);
            bwConfigure.RunWorkerAsync();
        }
        void bwConfigure_LoadData(object sender, DoWorkEventArgs e)
        {
            bwConfigure.ReportProgress(100,
                   new KeyValuePair<string, object>("TeamMember", _aClient.GetAllTeamMember()));

            bwConfigure.ReportProgress(100,
                   new KeyValuePair<string, object>("TaskGroupOwner", _aClient.GetAllTaskGroupOwner()));

            bwConfigure.ReportProgress(100,
                   new KeyValuePair<string, object>("TaskMaster", _aClient.GetAllConfig()));

            bwConfigure.ReportProgress(100,
                   new KeyValuePair<string, object>("TaskGroup", _aClient.GetAllTaskGroup()));

            bwConfigure.ReportProgress(100,
                   new KeyValuePair<string, object>("BindEvent", null));

            bwConfigure.ReportProgress(100,
                   new KeyValuePair<string, object>("ViewColumns", _aClient.GetViewColumn()));

            bwConfigure.ReportProgress(100,
                   new KeyValuePair<string, object>("ColumnSequence", _aClient.GetViewColumnSequence()));
        }
        private void btnAddTaskGroup_Click(object sender, EventArgs e)
        {
            try
            {
                if(String.IsNullOrEmpty(txtNewGroup.Text.Trim()))
                    throw new Exception("Group name can not be empty.");

                int groupID = _aClient.AddTaskGroup(txtNewGroup.Text.Trim());

                string owner = "";
                if(cbOwner.SelectedValue != null)
                    owner = cbOwner.SelectedValue.ToString();

                _aClient.AddTaskGroupOwner(groupID, owner);


                tgOwnersList.Add(new TaskGroupOwner(groupID, owner));
                ReloadControl(new KeyValuePair<string, object>("TaskGroupOwner", tgOwnersList));

                List<TaskGroup> taskGroupList = (List<TaskGroup>)lstGroups.DataSource;
                TaskGroup tg = new TaskGroup(groupID, txtNewGroup.Text.Trim());
                tg.GroupOwners = owner;
                taskGroupList.Add(tg);
                _autoLoadOn = true;
                ReloadControl(new KeyValuePair<string, object>("TaskGroup", taskGroupList));
                txtNewGroup.Text = "";
                _autoLoadOn = false;
            }
            catch(Exception exc)
            {
                AlertBox.ShowDialog(exc.Message);
            }
        }

        private void btnAddUser_Click(object sender, EventArgs e)
        {
            try
            {
                if(String.IsNullOrEmpty(txtNewUser.Text.Trim()))
                    throw new Exception("Users name can not be empty.");

                string manager="";
                if(cbManager.SelectedValue != null)
                    manager = cbManager.SelectedValue.ToString();

                _aClient.AddTeamMember(txtNewUser.Text.Trim(), manager);

                List<TeamMember> tMemberList = teamMemberArray.ToList();
                tMemberList.Add(new TeamMember(txtNewUser.Text.Trim(), manager));
                _autoLoadOn = true;
                ReloadControl(new KeyValuePair<string, object>("TeamMember", tMemberList));
                txtNewUser.Text = "";
                _autoLoadOn = false;

                teamMemberArray = tMemberList.ToArray();
            }
            catch(Exception exc)
            {
                AlertBox.ShowDialog(exc.Message);
            }
        }
        private void TaskSettings_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(this.DialogResult != DialogResult.OK)
            {
                if(((Form)tpConnection.Controls[0]).DialogResult == DialogResult.None)
                    this.DialogResult = DialogResult.Cancel;
                else
                    this.DialogResult = ((Form)tpConnection.Controls[0]).DialogResult;
            }
        }

        private void lstVisibleColumn_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            _cat.AddUpdaeApplicationSettingParameter("TaskViewColumnSequence", 
                string.Join(",", lstVisibleColumn.CheckedItems.OfType<string>().ToArray()));
        }

        private void btnApply_Click(object sender, EventArgs e)
        {
            _cat.AddUpdaeApplicationSettingParameter("UpdateInterval", updateInterval.Value.ToString());

            foreach(DataGridViewRow dr in dgvMasterData.Rows)
            {
                try
                {
                    _aClient.UpdateTaskMaster(dr.Cells[0].Value.ToString(), dr.Cells[1].Value.ToString());
                }
                catch(Exception exc)
                {
                    Console.WriteLine(exc.Message);
                }
            }

            this.DialogResult = DialogResult.OK;
            this.Close();
        }
    }
}
